package com.smarttest.common.util;

import java.io.File;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/**
 * xml方式解析hbase公共类
 * @author Huoyunren
 *
 */
public class HbaseXMLAnalysis {
	private Document doc = null;
	public HbaseXMLAnalysis(String xmlfile){
		SAXReader saxReader = new SAXReader();
		try {
			doc = saxReader.read(new File(xmlfile));
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 获得hbase设置
	 * @param hbasename xml中最外层name属性对应值
	 * @return
	 */
	public Map<String,String> getHbaseSetting(String hbasename) {
		Element hbase = getHbase(hbasename);
		List<?> l = hbase.element("properties").elements("property");
		Map<String,String> m = new HashMap<String, String>();
		for (Object o : l) {
			m.put(((Element)o).attributeValue("name"), ((Element)o).attributeValue("value"));
		}
		return m;
	}
	/**
	 * 获得所有hbase
	 * @return
	 */
	public  List<String> getHbases() {
		Element root = doc.getDocument().getRootElement();
		List<String> hbasename = new ArrayList<String>();
		for (Object e : root.elements("hbase")) {
			hbasename.add(((Element)e).attributeValue("name"));
		};
		return hbasename;
	}
	/**
	 * 获得指定hbase
	 * @param hbasename
	 * @return
	 */
	public Element getHbase(String hbasename) {
		Element root = doc.getDocument().getRootElement();
		List l = root.elements();
		Element e = null;
		for (Object o : l) {
			Element ee = (Element)o;
			if (null != ee.attribute("name") && ee.attributeValue("name").equalsIgnoreCase(hbasename)){
				e = ee;
				break;
			}
		}
		return e;
	}
	/**
	 * 获得所有指定hbase的table
	 * @param hbasename
	 * @return
	 */
	public List<String> getTables(String hbasename) {
		List<String> tables = new ArrayList<String>();
		for (Object e : getHbase(hbasename).element("tables").elements("table")) {
			tables.add(((Element)e).attributeValue("name"));
		};
		return tables;
	}
	/**
	 * 获得指定table
	 * @param hbasename
	 * @param tbname
	 * @return
	 */
	public Element getTable(String hbasename,String tbname) {
		List<?> l = getHbase(hbasename).element("tables").elements("table");
		Element table = null;
		for (Object e : l) {
			Element ee = (Element)e;
			if (null != ee.attribute("name") && ee.attributeValue("name").equalsIgnoreCase(tbname)){
				table = ee;
				break;
			}
		};
		return table;
	}
	/**
	 * 获得rowkey
	 * @param hbasename
	 * @param tbname
	 * @return
	 */
	public JSONArray getRowkeysNoValue(String hbasename,String tbname) {
		Element e = getTable(hbasename, tbname);
		JSONArray JA = new JSONArray();
		for (Object o : e.element("rowkey").elements("key")) {
			Element ee = (Element)o;
			if (null != ee.attribute("value")) {
				continue;
			}
			JSONObject jo = new JSONObject();
			for (Iterator i  = ee.attributeIterator();i.hasNext();) {
				Attribute a = (Attribute)i.next();
				jo.put(a.getName(), a.getValue());
			}
			JA.add(jo);
		};
		return JA;
	}
	/**
	 * 根据xml配置拼装rowkey
	 * @param hbasename
	 * @param tbname
	 * @param params
	 * @return
	 */
	public String getRowkey (String hbasename,String tbname,Map<String,Object> params) {
		Element rowkey = getTable(hbasename, tbname).element("rowkey");
		String rowkeystr = "";
		if (null != rowkey.attribute("class-name") && null != rowkey.attribute("method")) {
			String clsname = rowkey.attributeValue("class-name");
			String method = rowkey.attributeValue("method");
		}
		else {
			List<?> l = rowkey.elements("key");
			for(Object o : l) {
				String tmpstr = "";
				Element e = (Element)o;
				String type = e.attributeValue("type");
				String name = e.attributeValue("name");
				if (null != e.attribute("value")) {
					tmpstr = e.attributeValue("value");
				}
				else {
					if (type.equalsIgnoreCase("time")) {
						SimpleDateFormat df = new SimpleDateFormat(e.attributeValue("format"));
						tmpstr = df.format((Date)(params.get(name)));
					}
					else if (type.equalsIgnoreCase("timestamp")) {
						if (null != e.attribute("stamptype") && e.attributeValue("stamptype").equals("1")) {
							tmpstr = Long.toString(((Date)(params.get(name))).getTime());
						}
						else if (null != e.attribute("stamptype") && e.attributeValue("stamptype").equals("2")) {
							tmpstr = Long.toString(((Date)(params.get(name))).getTime()/1000);
						}
					}
					else{
						tmpstr = params.get(name).toString();
					}
				}				
				if (null != e.attribute("reverse") && e.attributeValue("reverse").equalsIgnoreCase("true")) {
					tmpstr = getReverseString(tmpstr);
				}
				if (null != e.attribute("usemd5") && e.attributeValue("usemd5").equalsIgnoreCase("true")) {
					tmpstr = string2MD5(tmpstr);
				}
				rowkeystr += tmpstr;
			}
		}
		if (null != rowkey.attribute("usemd5") && rowkey.attributeValue("usemd5").equalsIgnoreCase("true")) {
			rowkeystr = string2MD5(rowkeystr);
		}
		return rowkeystr;
	}
    /**
     * 获得倒序字符串
     * @param str
     * @return
     */
    public static String getReverseString(String str) {
    	return new StringBuffer(str).reverse().toString();
    }
    
    /**
	 * 将字符串转换成MD5编码
	 * 
	 * @param inStr
	 * @return String
	 */
	public static String string2MD5(String inStr) {
		String re_md5 = new String();
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(inStr.getBytes());
			byte b[] = md.digest();

			int i;

			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}

			re_md5 = buf.toString().toUpperCase();

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return re_md5;
	}
//	public static void main(String[] args) throws IOException, ParseException {
//		HbaseXMLAnalysis hxa = new HbaseXMLAnalysis();
//		Map<String,Object> m = new HashMap<String, Object>();
//		m.put("imei", "316513003033400");
//		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		m.put("timestamp", df.parse("2016-08-06 18:38:35"));
//		String k1 = hxa.getRowkey("hbase1", "dsp_ems_detail", m);
//		System.out.println(k1);
////		System.out.println(hxa.getRowkey("hbase1", "new_lc_daily", m));
//		Map<String,String> m2 = hxa.getHbaseSetting("hbase1");
//		Configuration conf =  HBaseConfiguration.create();
//		for (Entry<String, String> entry : m2.entrySet()) {
//			conf.set(entry.getKey(), entry.getValue());
//		}
//		Get get = new Get(Bytes.toBytes(k1));
//        HTable table = new HTable(conf, Bytes.toBytes("dsp_ems_detail"));// 获取表
//        Result result = table.get(get);
//        for (KeyValue kv : result.list()) {
//            System.out.println("family:" + Bytes.toString(kv.getFamily()));
//            System.out
//                    .println("qualifier:" + Bytes.toString(kv.getQualifier()));
//            System.out.println("value:" + Bytes.toString(kv.getValue()));
//            System.out.println("Timestamp:" + kv.getTimestamp());
//            System.out.println("-------------------------------------------");
//        }
//	}
}